package com.dfd.mango.admin.security;

import com.dfd.mango.admin.util.PasswordEncoder;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;

/*
 *文件名: JwtAuthenticationProvider
 *创建者: 东东
 *创建时间:2021/8/18 15:50
 *描述: 身份认证提供者
 *  springsecurity的登录验证逻辑是交由ProviderManager负责的，实际验证的时候又会调用AuthenticationProvider的authenticate进行认证，
 *  默认为DaoAuthenticationProvider，覆盖additionalAuthenticationChecks来完成密码匹配
 */
public class JwtAuthenticationProvider extends DaoAuthenticationProvider {

    public JwtAuthenticationProvider(UserDetailsService service) {
        setUserDetailsService(service);
    }

    // 自定义密码匹配
    @Override
    protected void additionalAuthenticationChecks(UserDetails userDetails, UsernamePasswordAuthenticationToken authentication) throws AuthenticationException {
        if (authentication.getCredentials() == null) {
            logger.debug("身份验证失败：未身份提供凭据！");
            throw new BadCredentialsException(messages.getMessage("AbstractUserDetailsAuthenticationProvider.badCredentials", "Bad credentials"));
        }
        // 获取未加密的密码 明文
        String presentedPassword = authentication.getCredentials().toString();
        String salt = ((JwtUserDetails) userDetails).getSalt();
        if (!new PasswordEncoder(salt).matches(userDetails.getPassword(), presentedPassword)) {
            logger.debug("身份验证失败：密码与存储值不匹配！");
            throw new BadCredentialsException(messages.getMessage("AbstractUserDetailsAuthenticationProvider.badCredentials", "Bad credentials"));
        }
    }
}
